import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Pattern;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;

	/**
	 * interface between the server and client
	 * @author Johannes
	 *
	 */
public class HTTPConnection {
	
	/**
	 * Send the command to get the coordinates from the current position which are stored at the server
	 * @return the x and y coordinates from the current position 
	 */
	public PositionXY httpGetXYCoordinates(String spotID){
		//setup the NameValuePair for the query
	    NameValuePair nvp1= new NameValuePair("command","getXY");
	    NameValuePair nvp2= new NameValuePair("spotID",spotID);
	    NameValuePair[] query =new NameValuePair[]{nvp1,nvp2};
	    HashMap<String,String >response=null;
	    //send the HTTP GET 
	    response=httpGET(query);
	    //evaluate the response and return the received coordinates
	    PositionXY pos=new PositionXY();
	    pos.setSpotID(spotID);
	    pos.setX(Integer.parseInt(response.get("X")));
	    pos.setY(Integer.parseInt(response.get("Y")));	
	    return pos;
	}
	
	/**
	 * Send the the corrected coordinates to the server
	 * @param x is the x coordinate
	 * @param y is the y coordinate
	 */
	public void httpSendCorrectedXYCoordinates(String spotID,int x,int y){
		//setup the NameValuePair for the query
		NameValuePair nvp1= new NameValuePair("command","sendCorrectedXYCoordinates");
	    NameValuePair nvp2= new NameValuePair("SpotId",spotID);
	    NameValuePair nvp3= new NameValuePair("X",String.valueOf(x));
	    NameValuePair nvp4= new NameValuePair("Y",String.valueOf(y));
	    NameValuePair[] query =new NameValuePair[]{nvp1,nvp2,nvp3,nvp4};
	    //send the HTTP GET 
	    httpGET(query);
	}
	
	/**
	 * Send the command to get all reference points which are stored on the server
	 * @return all reference points which are stored at the server 
	 */
	public ArrayList<PositionXY> httpGetReferencePoints(){
		//setup the NameValuePair for the query
		ArrayList<PositionXY> refPoints= new ArrayList<PositionXY>();
		NameValuePair nvp1= new NameValuePair("command","getReferencePoints");
	    NameValuePair[] query =new NameValuePair[]{nvp1};
	    HashMap<String,String >response=null;
	    //send the HTTP GET 
	    response=httpGET(query);
		//evaluate the response and store the different reference points in the ArrayList refPoints
		for(int i=0;i<response.size()/2;i++){
			PositionXY pos=new PositionXY();
		    pos.setX(Integer.parseInt(response.get("X"+i)));
			pos.setY(Integer.parseInt(response.get("Y"+i)));	
			refPoints.add(pos);
		}
		return refPoints;
	}
	
	/**
	 * Send the command to add a sample to a reference point on the server
	 * @param x is the x coordinate
	 * @param y is the y coordinate
	 * @param sampleCount is the number how many packets are sampled 
	 * @param keepTable if true the sample will be attached to the last table and if false a new table will be created 
	 */
	public void httpAddSampleToReferencePoint(int x,int y,int sampleCount,boolean keepTable){
		//setup the NameValuePair for the query
		NameValuePair nvp1= new NameValuePair("command","AddSampleToReferencePoint");
	    NameValuePair nvp2= new NameValuePair("X",String.valueOf(x));
	    NameValuePair nvp3= new NameValuePair("Y",String.valueOf(y));
	    NameValuePair nvp4= new NameValuePair("sampleCount",String.valueOf(sampleCount));
	    NameValuePair nvp5= new NameValuePair("keepTable",String.valueOf(keepTable));
	    NameValuePair[] query =new NameValuePair[]{nvp1,nvp2,nvp3,nvp4,nvp5};
	    //send the HTTP GET
	    httpGET(query);
	}
	
	/**
	 * Send the command to add a reference point to the server
	 * @param x is the x coordinate
	 * @param y is the y coordinate
	 * @param sampleCount is the number how many packets are sampled 
	 */
	public void httpAddReferencePoint(int x,int y,int sampleCount){
		//setup the NameValuePair for the query
		NameValuePair nvp1= new NameValuePair("command","AddReferencePoint");
	    NameValuePair nvp2= new NameValuePair("X",String.valueOf(x));
	    NameValuePair nvp3= new NameValuePair("Y",String.valueOf(y));
	    NameValuePair nvp4= new NameValuePair("sampleCount",String.valueOf(sampleCount));
	    NameValuePair[] query =new NameValuePair[]{nvp1,nvp2,nvp3,nvp4};
	    //send the HTTP GET
	    httpGET(query);
	}
	
	/**
	 * Checks if the server has finished collecting samples
	 * @return false if the server is still collecting samples and true if the server is finished 
	 */
	public boolean httpisRefPointSamplingFinished(){
		//setup the NameValuePair for the query
		HashMap<String,String >response=null;
		NameValuePair nvp1= new NameValuePair("command","isRefPointSamplingFinished");
	    NameValuePair[] query =new NameValuePair[]{nvp1};
	    //send the HTTP GET and receive the response
	    response=httpGET(query);
	    //evaluate the response and return if the server has finished collecting samples
	    return Boolean.parseBoolean(response.get("RefPointSamplingFinished"));
	}
	
	/**
	 * Send the command to remove a reference point at the server
	 * @param x is the x coordinate
	 * @param y is the y coordinate
	 */
	public void httpRemoveRefPoint(int x,int y){
		//setup the NameValuePair for the query
		NameValuePair nvp1= new NameValuePair("command","RemoveRefPoint");
	    NameValuePair nvp2= new NameValuePair("X",String.valueOf(x));
	    NameValuePair nvp3= new NameValuePair("Y",String.valueOf(y));
	    NameValuePair[] query =new NameValuePair[]{nvp1,nvp2,nvp3};
	    //send the HTTP GET
	    httpGET(query);
	}
	
	/**
	 * Send the command to remove all reference points at the server
	 */
	public void httpClearAllRefPoints(){
		//setup the NameValuePair for the query
		NameValuePair nvp1= new NameValuePair("command","ClearAllRefPoints");
	    NameValuePair[] query =new NameValuePair[]{nvp1};
	    //send the HTTP GET
	    httpGET(query);
	}
	
	/**
	 * Send the command to stop the sampling for positioning at the server
	 */
	public void httpStopPositioning() {
		//setup the NameValuePair for the query
		NameValuePair nvp1= new NameValuePair("command","StopPositioning");
	    NameValuePair[] query =new NameValuePair[]{nvp1};
	    //send the HTTP GET
	    httpGET(query);	
		
	}
	
	
	//TODO delete?
	private int testGETXYCounter=0;
	private int testPosX=0;
	private int testPosY=0;
	public PositionXY httpTestGetXYCoordinates(String spotID){
		
	    PositionXY pos=new PositionXY();
	    pos.setSpotID(spotID);
	    pos.setX(testPosX);
	    pos.setY(testPosY);
	    testPosX++;
	    testPosY++;
		testGETXYCounter++;
	    return pos;
	}

	//TODO delete?
	private int testRefX=0;
	private int testRefY=0;
	public ArrayList<PositionXY> httpTestGetReferencePoints(){
		testRefX=0;
		testRefY=0;
		ArrayList<PositionXY> refPoints= new ArrayList<PositionXY>();
		for(int i=0;i<4;i++){
			PositionXY pos=new PositionXY();
		    pos.setX(testRefX);
			pos.setY(testRefY);
			refPoints.add(pos);
			testRefX+=100;
			testRefY+=100;
		}		
		return refPoints;
	}
	
	private HashMap<String,String > httpGET(NameValuePair[] query){
		//Setup for the HTTP connection
		HashMap<String,String >response=null;
		String url ="http://localhost:8080";
	    HttpClient client = new HttpClient();
	    HttpMethod method = new GetMethod(url);
	    method.setQueryString(query);
	    try{
	    	//send the HTTP GET to the server
	        int statusCode = client.executeMethod(method);
	        //gets the response from the server
	        if(statusCode==200)
	        {
	        	//If the server answers with status OK the response is read
		        String responseString=method.getResponseBodyAsString();
		        response = new HashMap<String,String>(  );  
		        parseGetResponse(responseString, response);  
		        method.releaseConnection();
	        }      
	    }
	    catch(IOException e) {
	        e.printStackTrace();
	    }
	    return response;
	}
	
	private void parseGetResponse(String responseString,HashMap<String, String> response) {
		Pattern p = Pattern.compile("[\\{\\}\\=\\, ]++");
		//splits the response message string into its segments 
		String[] split = p.split( responseString );
		for ( int i=1; i< split.length; i+=2 )
		{
			response.put( split[i], split[i+1] );
		}
	}






}
